package config

import (
	"cloud_android_backend/pkg/version"
	"fmt"
	"log"
	"modules.tenxcloud.com/common/composite"
	"modules.tenxcloud.com/common/contract"
	"modules.tenxcloud.com/common/utility"
	"os"
	"runtime"
)

// AppConfig 定义你的配置结构
type AppConfig struct {
	Server struct {
		Host string `yaml:"host"`
		Port int    `yaml:"port"`
	} `yaml:"server"`
	Database struct {
		Username string `yaml:"username"`
		Password string `yaml:"password"`
		Host     string `yaml:"host"`
		Port     int    `yaml:"port"`
		Name     string `yaml:"name"`
	} `yaml:"database"`
	Logging struct {
		Level  string `yaml:"level"`
		Output string `yaml:"output"`
	} `yaml:"logging"`
	WechatPay WechatPayConfig `yaml:"wechatpay"`
	Alipay    AlipayConfig    `yaml:"alipay"`
}
type WechatPayConfig struct {
	AppID               string `yaml:"appid"`
	MchID               string `yaml:"mchid"`
	MchCertSerialNumber string `yaml:"mch_cert_serial_number"`
	PublicKeyID         string `yaml:"public_key_id"`
	PrivateKeyPath      string `yaml:"private_key_path"`
	PublicKeyPath       string `yaml:"public_key_path"`
	NotifyUrl           string `yaml:"notify_url"`
	ApiV3Key            string `yaml:"apiv3_key"`
}
type AlipayConfig struct {
	Aes        string `yaml:"aes"`
	AppId      string `yaml:"appid"`
	PrivateKey string `yaml:"private_key"`
	PublicKey  string `yaml:"public_key"`
	NotifyUrl  string `yaml:"notify_url"`
	ReturnUrl  string `yaml:"return_url"`
}

var Config *AppConfig

func InitConfig() {
	configPath := "config.yaml"
	if os.Getenv("CONFIG_PATH") != "" {
		configPath = os.Getenv("CONFIG_PATH")
	}
	// 创建配置加载器
	loader := NewYAMLConfigLoader()
	Config = &AppConfig{}
	// 从默认路径加载
	err := loader.Load(Config)
	if err != nil {
		// 如果默认路径失败，尝试指定路径
		err = loader.LoadFromPath(configPath, Config)
		if err != nil {
			log.Fatalf("Failed to load config: %v", err)
		}
	}

}

func init() {
	InitConfig()
}
func GetConfig() *AppConfig {
	if Config == nil {
		InitConfig()
	}
	return Config
}
func NewService(b contract.Configuration) *service {
	s := &service{
		Configuration: b,
		listenPort:    listenPort(),
	}
	data(s)
	return s
}

type service struct {
	contract.Configuration
	listenPort utility.Lazy
	data       utility.Lazy
}

// setting listen Port for server
func (s *service) ListenPort() (port string) {
	utility.Must(s.listenPort.Value(&port))
	return
}

func listenPort() utility.Lazy {
	return utility.NewLazy(func() (value interface{}, err error) {
		value = fmt.Sprintf("0.0.0.0:%s", utility.GetEnv("AlERT_PORT", "8082"))
		return
	})
}

func data(s *service) {
	info := utility.NewLazy(func() (value interface{}, err error) {
		json := composite.JSON
		baseCfgStr, _ := json.MarshalToString(s.Configuration.Data())
		var b map[string]interface{}
		utility.Must(json.UnmarshalFromString(baseCfgStr, &b))
		b["version"] = version.GetBuildVersion()
		b["listenPort"] = s.ListenPort()
		b["golang"] = runtime.Version()
		value = b
		return
	})
	s.data = info
}

// Additional information for server
func (s *service) Data() interface{} {
	var data map[string]interface{}
	utility.Must(s.data.Value(&data))
	return data
}
